﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MediaDefinitionAuditServiceTests.cs" company="DST Nexdox">
//   Copyright (c) DST Nexdox. All rights reserved.
// </copyright>
// <summary>
//   Defines the MediaDefinitionAuditServiceTests type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ServiceTests
{
  using System;
  using System.Collections.Generic;
  using DocProcessingRepository.Interfaces;
  using Entities;
  using Exceptions;
  using FluentAssertions;
  using Moq;
  using NUnit.Framework;
  using ServiceInterfaces;
  using Services;

  [Category("Unit")]
  [TestFixture]
  public class MediaDefinitionAuditServiceTests
  {
    private Mock<IMediaDefinitionAuditRepository> mediaDefinitionAuditRepositoryMock;
    private IMediaDefinitionAuditService mediaDefinitionAuditService;

    [SetUp]
    public void Setup()
    {
      this.mediaDefinitionAuditRepositoryMock = new Mock<IMediaDefinitionAuditRepository>();
      this.mediaDefinitionAuditService = new MediaDefinitionAuditService(this.mediaDefinitionAuditRepositoryMock.Object);
    }

    [Test]
    public void GivenAMediaDefinitionId_WhenIGetTheMediaDefinitionAudits_TheyAreRetrievedFromTheDatabase()
    {
      var mediaDefinitionAuditsToReturn = new List<MediaDefinitionAuditEntity>
                                {
                                  new MediaDefinitionAuditEntity
                                    {
                                      MediaDefinitionAuditId
                                        = 1,
                                      MediaDefinitionId
                                        = 1
                                    }
                                };

      this.mediaDefinitionAuditRepositoryMock.Setup(m => m.GetAudits(It.IsAny<Int32>()))
        .Returns(mediaDefinitionAuditsToReturn);

      var result = this.mediaDefinitionAuditService.GetAudits(1);

      var resultAsObj = (Object)result;
      resultAsObj.Should().BeSameAs(mediaDefinitionAuditsToReturn);
    }

    [Test]
    public void GivenAMediaDefinitionId_WhenIGetTheMediaDefinitionAudits_AndTheDatabaseIsUnavailable_ADocProcessingExceptionIsRaised()
    {
      this.mediaDefinitionAuditRepositoryMock.Setup(m => m.GetAudits(It.IsAny<Int32>())).Throws<Exception>();

      Action act = () => this.mediaDefinitionAuditService.GetAudits(1);

      act.ShouldThrow<DocProcessingException>();
    }

    [Test]
    public void GivenAMediaDefinitionId_WhenICreateAMediaDefinitionAudit_ItIsAddedToTheDatabase()
    {
      var createdMediaDefinitionAudit = new MediaDefinitionAuditEntity() { MediaDefinitionAuditId = 1 };

      this.mediaDefinitionAuditRepositoryMock.Setup(
        m =>
        m.AddAudit(
          It.IsAny<Int32>(),
          It.IsAny<String>(),
          It.IsAny<MediaDefinitionAudit.MediaDefinitionAuditType>(),
          It.IsAny<DateTime>(),
          It.IsAny<String>()))
      .Returns(createdMediaDefinitionAudit);

      MediaDefinitionAuditEntity result = this.mediaDefinitionAuditService.AddAudit(
        2,
        "user",
        MediaDefinitionAudit.MediaDefinitionAuditType.MediaStockStationNumbersUpdated,
        new DateTime(2015, 1, 1),
        "details");

      this.mediaDefinitionAuditRepositoryMock.Verify(
        m =>
        m.AddAudit(
          2,
          "user",
          MediaDefinitionAudit.MediaDefinitionAuditType.MediaStockStationNumbersUpdated,
          new DateTime(2015, 1, 1),
          "details"),
        Times.Once);

      var resultObj = (Object)result;
      resultObj.Should().BeSameAs(createdMediaDefinitionAudit);
    }

    [Test]
    public void GivenAMediaDefinitionId_WhenICreateAMediaDefinitionAuditg_AndTheDatabaseIsUnavailable_ADocProcessingExceptionIsRaised()
    {
      this.mediaDefinitionAuditRepositoryMock.Setup(
        m =>
        m.AddAudit(
          It.IsAny<Int32>(),
          It.IsAny<String>(),
          It.IsAny<MediaDefinitionAudit.MediaDefinitionAuditType>(),
          It.IsAny<DateTime>(),
          It.IsAny<String>()))
      .Throws<Exception>();

      Action act = () => this.mediaDefinitionAuditService.AddAudit(
        2,
        "user",
        MediaDefinitionAudit.MediaDefinitionAuditType.MediaStockStationNumbersUpdated,
        new DateTime(2015, 1, 1),
        "details");

      act.ShouldThrow<DocProcessingException>();
    }
  }
}
